package edu.neu.cs6515.net.test.unit;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import junit.framework.Assert;

import org.junit.Before;
import org.junit.Test;

import com.google.common.collect.Lists;

import edu.neu.cs6515.net.AdministratorProxy;
import edu.neu.cs6515.net.InputOutputException;
import edu.neu.cs6515.player.Player;
import edu.neu.cs6515.player.strategy.SimpleStepStrategy;
import edu.neu.cs6515.player.strategy.StrategyException;
import edu.neu.cs6515.xml.Board;
import edu.neu.cs6515.xml.IngeniousColor;
import edu.neu.cs6515.xml.Placement;
import edu.neu.cs6515.xml.Score;
import edu.neu.cs6515.xml.Tile;
import edu.neu.cs6515.xml.w12.Accept;
import edu.neu.cs6515.xml.w12.End;
import edu.neu.cs6515.xml.w12.PlayerNames;
import edu.neu.cs6515.xml.w12.Register;
import edu.neu.cs6515.xml.w12.Rerackable;
import edu.neu.cs6515.xml.w12.TurnResult;
import edu.neu.cs6515.xml.w12.XMLTurn;

public class testAdministratorProxy {

    private PredefinedInOutPut inOut;

    @Before
    public void setUp() {
        inOut = new PredefinedInOutPut();
    }

    /**
     * test register a player
     */
    @Test
    public void testRegisterPlayer() {
        ArrayList<Tile> tilesInHand = Lists.newArrayList(new Tile(IngeniousColor.RED, IngeniousColor.RED),
                new Tile(IngeniousColor.RED, IngeniousColor.RED),
                new Tile(IngeniousColor.RED, IngeniousColor.RED));
        List<Object> recieves = new ArrayList<Object>(Lists.newArrayList(new Accept(2,
                tilesInHand)));
        inOut.setReceives(recieves);

        AdministratorProxy adminProxy = new AdministratorProxy(inOut);
        Player player = new Player("player", new SimpleStepStrategy(new LinkedList<Placement>()));
        try {
            adminProxy.registerPlayer(player.getPlayersName(),
                    player);
        } catch (Throwable t) {
        }
        Object obj = inOut.popOldestResponse();
        Assert.assertTrue(new Register("player").equals(obj));
        Assert.assertEquals(2, player.getNumberOfPlayers());
        Assert.assertEquals(3, player.getTilesInHand().size());
        Assert.assertEquals(tilesInHand.get(0), player.getTilesInHand().get(0));
        Assert.assertEquals(tilesInHand.get(1), player.getTilesInHand().get(1));
        Assert.assertEquals(tilesInHand.get(2), player.getTilesInHand().get(2));
    }

    @Test
    public void testListenAndRespond() throws InputOutputException, StrategyException {

        Placement playerPlacement = new Placement(IngeniousColor.ORANGE, IngeniousColor.ORANGE, 5, 1, 5, 2);
        Player player = new Player("player",
                new SimpleStepStrategy(Lists.newArrayList(
                        playerPlacement)));

        AdministratorProxy adminProxy = new AdministratorProxy(inOut);
        adminProxy.registerPlayer("player",
                player);
        Object obj = inOut.popOldestResponse();
        Assert.assertTrue(new Register("player").equals(obj));

        ArrayList<Tile> tilesBag = Lists.newArrayList(new Tile(IngeniousColor.PURPLE, IngeniousColor.PURPLE));

        Board xmlBoard = new Board(Lists.newArrayList(new Placement(IngeniousColor.ORANGE,
                IngeniousColor.ORANGE, 5, 6, 5, 7)), 2);
        ArrayList<Tile> tilesInHand = Lists.newArrayList(
                new Tile(IngeniousColor.ORANGE, IngeniousColor.ORANGE),
                new Tile(IngeniousColor.GREEN, IngeniousColor.GREEN),
                new Tile(IngeniousColor.GREEN, IngeniousColor.GREEN),
                new Tile(IngeniousColor.GREEN, IngeniousColor.GREEN),
                new Tile(IngeniousColor.GREEN, IngeniousColor.GREEN),
                new Tile(IngeniousColor.GREEN, IngeniousColor.GREEN));
        XMLTurn turn = new XMLTurn(xmlBoard,
                new Score(),
                tilesInHand);

        inOut.setReceives(Lists.newArrayList(
                new Accept(2, Lists.newArrayList(new Tile(IngeniousColor.RED, IngeniousColor.RED))),
                new PlayerNames(PlayerNames.fromStringToPlayerNames(Lists.newArrayList("player", "anotherPlayer"))),
                turn,
                new Tile(IngeniousColor.PURPLE, IngeniousColor.PURPLE),
                new TurnResult("anotherplayer", Lists.newArrayList(new Placement(IngeniousColor.GREEN, IngeniousColor.GREEN, 5, 1, 5, 2)))
                ));
        adminProxy.listenAndRespond();
        Assert.assertEquals(6, player.getTilesInHand().size());
        Assert.assertEquals(2, player.getNumberOfPlayers());
        Assert.assertTrue(player.getNameOfOpponents().contains("anotherPlayer"));
        Assert.assertTrue(player.getTilesInHand().contains(new Tile(IngeniousColor.PURPLE, IngeniousColor.PURPLE)));

        Assert.assertEquals(playerPlacement,
                inOut.popOldestResponse());
        Assert.assertTrue(inOut.popOldestResponse().equals(new Rerackable()));
        Assert.assertTrue(inOut.popOldestResponse().equals(new End()));
    }
}
